home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Languages / Masm V6.11 / SAMPLES / SHOW / SHOW.AS$ / SHOW.bin
Encoding:
Text File  |  1993-07-16  |  15.3 KB  |  453 lines

  1. ;* SHOW.ASM - Text file displayer for DOS.
  2.  
  3.         TITLE   Show
  4.         .MODEL  small, pascal   ; This code also works in tiny model
  5.         .DOSSEG
  6.  
  7.         INCLUDE show.inc
  8.         INCLUDE dos.inc
  9.         INCLUDE bios.inc
  10.  
  11.         .STACK
  12.  
  13.         .DATA
  14.  
  15. ; Status line
  16.  
  17. stLine  BYTE    "Line: 12345 "
  18. stFile  BYTE    "File: 12345678.123  "
  19.         BYTE    "Quit: Q  Next: ESC  Move:   PGUP PGDN HOME END"
  20.  
  21. ; Variables for    screen handling
  22.  
  23. yCur    WORD    1
  24. yMax    WORD    24              ; Number of rows - status line takes one more
  25. iMode   BYTE    0               ; Initial mode
  26. iPage   BYTE    0               ; Initial display page
  27. atInit  BYTE    0               ; Initial attribute
  28. shCsr   WORD    0               ; Initial cursor shape
  29. bCsrSta BYTE    0               ; 0 = cursor visible, position unchanged
  30.                                 ; 1 = cursor invisible, position unchanged
  31.                                 ; 2 = cursor invisible, position changed
  32.  
  33. fNewVid BYTE    0               ; Video change flag
  34. fCGA    BYTE    1               ; CGA flag - default yes
  35.  
  36. segVid  WORD    SEG_CLR         ; Video buffer address - default color
  37.  
  38. atSta   BYTE    STAT_CLR        ; Status line color
  39. celScr  LABEL   WORD            ; Cell (character and attribute)
  40. chScr   BYTE    ' '             ; Initialize to space
  41. atScr   BYTE    SCRN_CLR        ; Screen color
  42.  
  43. ; Buffer variables
  44.  
  45. fpBuf   LABEL   FAR PTR
  46. offBuf  WORD    0               ; Position in buffer (offset)
  47. segBuf  WORD    0               ; Base of buffer (segment)
  48. cbBuf   WORD    0               ; Length of buffer
  49.  
  50. ; File information
  51.  
  52. hFileIn WORD    0               ; Holds file handle on open
  53.  
  54. ; Buffer for file spec and structure for file info
  55.  
  56. achBuf  BYTE    NAME_MAX, ?     ; Buffer format for string input
  57. stFiles BYTE    NAME_MAX DUP (0); File spec string
  58. fiFiles FILEINFO <>             ; Wild card entry structure
  59. cFiles  WORD    0               ; Count of 1 or 0 files remaining
  60.  
  61. ; Messages
  62.  
  63. stMsg1  BYTE    13, 10, 13, 10, "Enter filename: $"
  64. stMsg2  BYTE    13, 10, "File problem. Try again? $"
  65. stMsg3  BYTE    13, 10, "File too large: $"
  66. stMsg4  BYTE    13, 10, "Memory problem.", 13, 10, "$"
  67. stMsg5  BYTE    13, 10, "Must have DOS 2.0 or higher", 13, 10, "$"
  68.  
  69. ; Call table
  70.  
  71. achKeys BYTE    71, 72, 73, 79, 80, 81, 'q', 'Q'; Key table
  72. afnKeys WORD    HomeKey                         ; Corresponding procedures
  73.         WORD    UpKey
  74.         WORD    PgUpKey
  75.         WORD    EndKey
  76.         WORD    DownKey
  77.         WORD    PgDnKey
  78.         WORD    Quit
  79.         WORD    Quit
  80.         WORD    UnknownKey
  81.  
  82.         .CODE
  83.         .STARTUP
  84.  
  85. ; Adjust memory allocation (works for tiny or small model)
  86.  
  87.         mov     bx, sp                  ; Convert stack pointer to paragraphs
  88.         mov     cl, 4                   ;   to get stack size
  89.         shr     bx, cl
  90.         mov     ax, ss                  ; Add SS to get end of program
  91.         add     ax, bx
  92.         mov     bx, es                  ; Get start of program
  93.         sub     ax, bx                  ; Subtract start from end
  94.         inc     ax
  95.         @ModBlock ax                    ; Release memory after program
  96.  
  97. ; Check DOS
  98.  
  99.         @GetVer                         ; Get DOS version
  100.         .IF     al < 2                  ; Requires DOS 2.0
  101.         @ShowStr stMsg5                 ;   else error and quit
  102.         int     20h
  103.         .ENDIF
  104.  
  105. ; Get command line and copy to filename buffer
  106.  
  107.         mov     di, 80h                 ; PSP offset of command line
  108.         mov     bl, es:[di]             ; Get length from first byte
  109.         sub     bh, bh
  110.         or      bx, bx
  111.         je      Prompter
  112.  
  113.         mov     WORD PTR es:[bx+81h], 0 ; Convert to ASCIIZ
  114.         mov     al, ' '                 ; Character to check for
  115.         inc     di                      ; Advance beyond count
  116.         mov     cx, 0FFFFh              ; Don't let count interfere
  117.         repe    scasb                   ; Find first nonspace
  118.         dec     di                      ; Adjust
  119.  
  120.         mov     si, di                  ; Filename source
  121.         mov     di, OFFSET stFiles      ; Name buffer destination
  122.         mov     bx, ds                  ; Save segment registers
  123.         mov     dx, es
  124.         mov     ds, dx                  ; DS = ES
  125.         mov     es, bx                  ; ES = DS
  126.         mov     cx, NAME_MAX            ; Count = max filename allowed
  127.  
  128.         .REPEAT
  129.         lodsb                           ; Copy characters
  130.         .BREAK .IF (al == ' ') || (al == 0) ; Stop at space or null
  131.         stosb
  132.         .UNTILCXZ                       ; Until name exceeds max
  133.  
  134.         mov     ds, bx                  ; Restore segments
  135.         mov     es, dx
  136.         mov     BYTE PTR [di], 0
  137.         jmp     FindFile
  138. NoFile:
  139.  
  140.         @ShowStr stMsg2                 ; Prompt to try again
  141.         @GetChar 0, 1, 0
  142.         and     al, 11011111y           ; Convert key to upper case
  143.         .IF     al != 'Y'               ; If not yes,
  144.         jmp     quit                    ;   quit
  145.         .ENDIF
  146.  
  147. ; Prompt for file
  148.  
  149. Prompter:
  150.         @ShowStr stMsg1                 ; Prompt for file
  151.         @GetStr achBuf, 0               ; Get response as ASCIIZ
  152.  
  153. ; Find first (or only) file in file spec
  154.  
  155. FindFile:
  156.  
  157.         @SetDTA <OFFSET fiFiles>        ; Set DTA to file info structure
  158.                                         ; Don't need DTA for anything else,
  159.                                         ;   so no need to restore it
  160.         @GetFirst stFiles,0             ; Find a matching file
  161.  
  162.         jc      NoFile                  ; If not found, prompt for new
  163.         inc     cFiles                  ; Some files remaining
  164.  
  165.         INVOKE  GetVid
  166.  
  167. ; Main program loop to process files
  168.  
  169.         .REPEAT
  170.  
  171. ; Copy filename to file spec
  172.  
  173.         mov     bCsrSta, 2              ; Cursor hidden, position unchanged
  174.         INVOKE  GetNamePos,             ; Get filename position in file spec
  175.                 ADDR stFiles
  176.  
  177.         mov     si, OFFSET fiFiles.fiFileName   ; Point to source name
  178.         push    ds                      ; ES = DS
  179.         pop     es
  180.         mov     di, ax                  ; Load address from return value
  181.  
  182.         .REPEAT                         ; Copy to (and including) null
  183.         movsb
  184.         .UNTIL BYTE PTR [si-1] == 0
  185.  
  186. ; Copy filename to status line
  187.  
  188.         mov     si, OFFSET fiFiles.fiFileName   ; Point to source name
  189.         mov     di, OFFSET stFile[FILE_POS]     ; Point to status line
  190.  
  191.         sub     cx, cx                  ; Count characters
  192.         .REPEAT
  193.         lodsb                           ; Copy to (but excluding) null
  194.         .BREAK .IF al == 0
  195.         stosb
  196.         inc     cx
  197.         .UNTIL  0
  198.  
  199.         mov     bx, 12                  ; Calculate blank spaces to fill
  200.         sub     bx, cx
  201.         mov     al, ' '                 ; Fill rest of name space with blanks
  202.         mov     cx, bx
  203.         rep     stosb
  204.  
  205. ; Skip any file that is larger than 64K
  206.  
  207.         .IF     WORD PTR fiFiles.fiSize[2] != 0 ; Error if high word isn't 0
  208.         mov     bCsrSta, 1              ; Cursor hidden, position unchanged
  209.  
  210.         @ShowStr stMsg3                 ; Display error string and filename
  211.         @Write   fiFiles.fiFileName, cx, 1
  212.  
  213.         .IF     cFiles                  ; If files remaining,
  214.         @GetChar 0                      ;   get a key
  215.         .ENDIF
  216.         .ENDIF
  217.  
  218. ; Allocate dynamic memory for file buffer
  219.  
  220.         mov     ax, WORD PTR fiFiles.fiSize[0]  ; Get length
  221.         mov     cbBuf, ax               ; Save
  222.         mov     offBuf, 0
  223.         mov     cl, 4                   ; Convert to paragraphs
  224.         shr     ax, cl
  225.         inc     ax                      ; Zero adjust
  226.  
  227.         @GetBlock ax                    ; Try to allocate 64K
  228.         .IF     carry?                  ; Display error and quit if
  229.         @ShowStr stMsg4                 ;   request failed
  230.         jmp     Quit
  231.         .ENDIF
  232.         mov     segBuf, ax              ; Save buffer segment
  233.  
  234. ; Open file and read contents into buffer
  235.  
  236.         @OpenFile stFiles, 0            ; Try to open
  237.         jc      NoFile                  ; If fail, get a new file
  238.         mov     hFileIn, ax             ; Save handle
  239.  
  240.         push    ds
  241.         @Read   fpBuf, cbBuf, hFileIn   ; Read file
  242.         pop     ds
  243.         .IF     carry?
  244.         jmp     NoFile                  ; If read error try again
  245.         .ENDIF
  246.  
  247. ; Search back for EOF marker and adjust    if necessary
  248.  
  249.         mov     di, cbBuf               ; Load file length
  250.         dec     di                      ;   and adjust
  251.         mov     es, segBuf
  252.         std                             ; Look backward for 255 characters
  253.         mov     cx, 0FFh
  254.         .IF     cx >= di
  255.         mov     cx, di
  256.         .ENDIF
  257.  
  258.         mov     al, 1Ah                 ; Search for EOF marker
  259.         repne   scasb
  260.         cld
  261.         .IF     cx != 0                 ; If found,
  262.         inc     di                      ;   adjust and save file size
  263.         mov     cbBuf, di
  264.         .ENDIF
  265.  
  266. ; Show a screen of text and allow commands
  267.  
  268.         INVOKE  Show
  269.  
  270.         @CloseFile hFileIn              ; Yes? Close file
  271.         @FreeBlock segBuf               ; Release buffer
  272.  
  273.         @GetNext
  274.  
  275.         .IF     carry?
  276.         dec     cFiles
  277.         .ENDIF
  278.         .UNTIL  !cFiles
  279.  
  280. ; Fall through to Quit
  281.  
  282. Quit    PROC
  283.  
  284.         cmp     bCsrSta, 1              ; Check cursor status
  285.         jg      csrvislast              ; 2 - Make cursor visible on last line
  286.         je      csrvis                  ; 1 - Make cursor visible
  287.         jmp     csrasis                 ; 0 - Leave cursor as is
  288.  
  289. csrvislast:
  290.         mov     dx, yMax                ; Load last row and first column
  291.         xchg    dl, dh
  292.         mov     cx, dx                  ; Make row the same
  293.         mov     dl, 79
  294.         @Scroll 0, atInit               ; Clear last line to original color
  295.         sub     dl, dl                  ; Column 0
  296.         @SetCsrPos                      ; Set cursor
  297. csrvis:                                 ; Fall through
  298.                                         ; Restore cursor attribute
  299.         @SetCsrSize <BYTE PTR shCsr[1]>, <BYTE PTR shCsr[0]>
  300.  
  301. csrasis:
  302.         .IF     fNewVid == 1
  303.         @SetMode iMode                  ; Restore video mode, page, and cursor
  304.         @SetPage iPage
  305.         .ENDIF
  306.  
  307.         .EXIT   0                       ; Quit
  308.  
  309. Quit    ENDP
  310.  
  311.  
  312. Show    PROC
  313.  
  314. ; Display first page
  315.  
  316.         mov     yCur, 1                 ; Reinitialize
  317.         INVOKE  Pager,                  ; Start at 0
  318.                 0
  319.  
  320. ; Handle keys
  321.  
  322.         .REPEAT
  323.  
  324.         @GetChar 0, 0, 0                ; Get a key
  325.  
  326.         .BREAK .IF al == 27             ; If ESC get out for next file
  327.  
  328.         ; If null or E0 (for extended keyboard), it's an extended key
  329.         .IF     (al == 0) || (al == 0E0h)
  330.         @GetChar 0, 0, 0                ; Get extended code
  331.         .ENDIF
  332.  
  333.         push    ds                      ; ES = DS
  334.         pop     es
  335.         mov     di, OFFSET achKeys      ; Load address and length of key list
  336.         mov     cx, LENGTHOF achKeys + 1
  337.         repne   scasb                   ; Find position and point to key
  338.         sub     di, OFFSET achKeys + 1
  339.         shl     di, 1                   ; Adjust pointer for word addresses
  340.         call    afnKeys[di]             ; Call procedure
  341.         .UNTIL  0
  342.  
  343.         ret
  344. Show    ENDP
  345.  
  346. HomeKey:
  347.         mov     offBuf, 0               ; HOME - set position to 0
  348.         mov     yCur, 1
  349.         INVOKE  Pager, offBuf
  350.         retn
  351.  
  352. UpKey:
  353.         INVOKE  Pager, -1               ; UP - scroll backward 1 line
  354.         retn
  355.  
  356. PgUpKey:
  357.         mov     ax, yMax                ; PGUP - Page back
  358.         neg     ax
  359.         INVOKE  Pager, ax
  360.         retn
  361.  
  362. EndKey:
  363.         mov     ax, cbBuf               ; END - Get last byte of file
  364.         dec     ax                      ; Zero adjust
  365.         mov     offBuf, ax              ; Make it the file position
  366.         mov     yCur, -1                ; Set illegal line number as flag
  367.         mov     ax, yMax                ; Page back
  368.         neg     ax
  369.         INVOKE  Pager, ax
  370.         retn
  371.  
  372. DownKey:
  373.         INVOKE  Pager, 1                ; DOWN - scroll forward 1 line
  374.         retn
  375.  
  376. PgDnKey:
  377.         INVOKE  Pager, yMax             ; PGDN - page forward
  378.         retn
  379.  
  380. UnknownKey:
  381.         retn                            ; Ignore unknown key
  382.  
  383.  
  384. ;* GetVid - Gets the video mode and sets related global variables.
  385. ;*
  386. ;* Params: None
  387. ;*
  388. ;* Return: Number of lines in current mode (25, 43, or 50)
  389.  
  390. GetVid  PROC
  391.  
  392. ; Adjust for current mode and and video adapter
  393.  
  394.         INVOKE  IsEGA                   ; EGA (or VGA)?
  395.         .IF     ax != 0                 ; If 0 must be CGA or MA
  396.         mov     yMax, ax                ; Load rows
  397.         dec     fCGA                    ; Not CGA
  398.         .ENDIF
  399.  
  400.         @GetMode                        ; Get video mode
  401.         mov     iMode, al               ; Save initial mode and page
  402.         mov     iPage, bh
  403.         mov     dl, al                  ; Work on copy
  404.         cmp     dl, 7                   ; Is it mono 7?
  405.         je      loadmono                ; Yes? Set mono
  406.         cmp     dl, 15                  ; Is it mono 15?
  407.         jne     graphchk                ; No? Check graphics
  408. loadmono:
  409.         mov     segVid, SEG_MONO        ; Load mono address
  410.         mov     atSta, STAT_BW          ; Set B&W defaults for status line
  411.         mov     atScr, SCRN_BW          ;   and screen background
  412.         dec     fCGA                    ; Not CGA
  413.         cmp     al, 15                  ; Is it mono 15?
  414.         jne     exit                    ; No? Done
  415.         mov     dl, 7                   ; Yes? Set standard mono
  416.         jmp     chmode
  417. graphchk:
  418.         cmp     dl, 7                   ; 7 or higher?
  419.         jg      color                   ; 8 to 14 are color (7 and 15 done)
  420.         cmp     dl, 4                   ; 4 or higher?
  421.         jg      bnw                     ; 5 and 6 are probably black and white
  422.         je      color                   ; 4 is color
  423.         test    dl, 1                   ; Even?
  424.         jz      bnw                     ; 0 and 2 are black and white
  425. color:                                  ; 1 and 3 are color
  426.         cmp     dl, 3                   ; 3?
  427.         je      exit                    ; Yes? Done
  428.         mov     dl, 3                   ; Change mode to 3
  429.         jmp     chmode
  430. bnw:
  431.         mov     atSta, STAT_BW          ; Set B&W defaults for status line
  432.         mov     atScr, SCRN_BW          ;   and screen background
  433.         cmp     dl, 2                   ; 2?
  434.         je      exit                    ; Yes? Done
  435.         mov     dl, 2                   ; Make it 2
  436. chmode:
  437.         @SetMode dl                     ; Set video mode
  438.         @SetPage 0                      ; Set video page
  439.         mov     fNewVid, 1              ; Set flag
  440. exit:
  441.         @GetCsr                         ; Get cursor shape (ignore position)
  442.         mov     shCsr, cx               ; Save shape
  443.         @GetCharAtr                     ; Read the cell at the cursor
  444.         mov     atInit, ah              ; Save attribute
  445.         @SetCsrSize 20h, 20h            ; Turn off cursor (invisible shape)
  446.  
  447.         ret
  448.  
  449. GetVid  ENDP
  450.  
  451.  
  452.         END
  453.